#include "iostream"

namespace eddy {
    class Person {
    public:
        // mutable 可以被常函数、常对象修改
        mutable int age;
        int score;
        float *ae;

        Person() {
            age = 0;
        };

        // 构造函数。初始化列表
        Person(int score) : score(score) {};

        // 拷贝构造函数，会在拷贝时调用
        Person(const Person &person) : score(person.score) {
            std::cout << "Person(const Person& person)" << std::endl;
        }

        // 方法可以被nullptr访问，但是要注意方法中不能访问类属性！！！要在方法中判断this != nullptr
        // 使用this指向对象本身
        Person &addAge(int n) {
            this->age += n;
            return *this;
        }

        // 普通函数方法
        void sum() {
            std::cout << this->age << std::endl;
        }

        // 常函数
        // 关键字在参数列表后。内部不允许修改属性值
        // 内部不允许调用普通函数，只能调用常函数
        void changeScore(int newScore) const {
            //  error score = newScore;
        }

        // 析构函数
        // 在对象销毁时执行，不能有参数
        ~Person() {
            std::cout << "~Person()" << std::endl;
            // 如果对象存在指针类型，销毁对象时，需要释放该对象
            if (ae != nullptr) {
                ae = nullptr;
            }
        }
    };
}

int main() {

//    eddy::Person *person = new eddy::Person(3);
//    std::cout << person->score << std::endl;
//
//    // 在堆中新建Person对象
//    person->ae = new float(1.0);
//    float *temp = person->ae;
//    delete person;
//
//    std::cout << temp << std::endl;
    // 使用链式操作
    eddy::Person p1;
    p1.addAge(10).addAge(10).addAge(10).sum();

    // 常对象
    // -使用 const Person p2;
    // -可以读取属性，但是不能修改属性，只能调用常函数
    return 0;
}